﻿namespace Creek.UI.EFML
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Windows.Forms;

    using Creek.UI.EFML.Base;

    public class ControlProvider
    {
        #region Fields

        public byte[] Assembly;

        public Dictionary<Tag, Type> Controls = new Dictionary<Tag, Type>();

        #endregion

        #region Public Indexers

        public Control this[Tag key]
        {
            get
            {
                Type t = this.Controls[key];
                var r = (Control)Activator.CreateInstance(t);
                return r;
            }
        }

        #endregion

        #region Public Methods and Operators

        public void Load(Stream s)
        {
            var br = new BinaryReader(s);
            var raw = new List<byte>();

            // load all Controls
            int cC = br.ReadInt32();
            for (int i = 0; i < cC; i++)
            {
                this.Controls.Add(Tag.FromString(br.ReadString()), Type.GetType(br.ReadString()));
            }

            // read raw assembly
            int c = br.ReadInt32();
            for (int i = 0; i < c; i++)
            {
                raw.Add(br.ReadByte());
            }
            this.Assembly = raw.ToArray();

            br.Close();
        }

        public void Save(Stream s)
        {
            var bw = new BinaryWriter(s);

            // write controls
            bw.Write(this.Controls.Count);
            foreach (var control in this.Controls)
            {
                bw.Write(control.Key.ToString());
                bw.Write(control.Value.FullName);
            }

            // write raw data
            bw.Write(this.Assembly.Length);
            foreach (var raw in this.Assembly)
            {
                bw.Write(raw);
            }

            bw.Flush();
            bw.Close();
        }

        #endregion

        #region Methods

        protected void Add<T>(Tag t)
        {
            this.Controls.Add(t, typeof(T));
        }

        #endregion
    }
}